package com.chucang.shucang.pms.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.chucang.shucang.common.base.page.PageData;
import com.chucang.shucang.common.base.utils.R;
import com.chucang.shucang.common.security.annotation.Inner;
import com.chucang.shucang.pms.constant.PmsCommonConstant;
import com.chucang.shucang.pms.entity.BlindBoxBaseEntity;
import com.chucang.shucang.pms.entity.BlindBoxMallEntity;
import com.chucang.shucang.pms.feign.vo.UserBlindBoxHoldEntity;
import com.chucang.shucang.pms.service.BlindBoxBaseService;
import com.chucang.shucang.pms.service.BlindBoxMallService;
import com.chucang.shucang.pms.vo.BlindBoxMallPageResVO;
import com.chucang.shucang.pms.vo.BlindBoxOnSaleDetailResVO;
import com.chucang.shucang.pms.vo.BlindBoxOnSalePageResVO;
import com.chucang.shucang.pms.vo.query.BlindBoxMallQuery;
import com.chucang.shucang.pms.vo.query.BlindBoxOnSaleQuery;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 盲盒商城表
 *
 * @author flitsneak flitsneak@gmail.com
 * @since 1.0.0 2022-09-12
 */
@RestController
@RequestMapping("/blindboxmall")
@RequiredArgsConstructor
@Api(tags = "盲盒商城表")
public class BlindBoxMallController {

    private final BlindBoxMallService blindBoxMallService;

    private final BlindBoxBaseService blindBoxBaseService;

    private final ThreadPoolTaskExecutor pmsExecutor;

    /**
     * 盲盒商品首页分页
     *
     * @param blindBoxMallQuery bbq
     * @return r
     */
    @Cacheable(value = "blindBoxMallPage", key = "{#blindBoxMallQuery.page}", unless = "#blindBoxMallQuery.fuzzy!=null")
    @PostMapping("/blindBoxMallPage")
    public R<PageData<BlindBoxMallPageResVO>> collectionMallPage(@Valid @RequestBody BlindBoxMallQuery blindBoxMallQuery) {
        //分页查询藏品数据
        PageData<BlindBoxBaseEntity> baseEntityPageData = blindBoxBaseService.blindBoxBasePage(blindBoxMallQuery);
        HashMap<Long, String> stringHashMap = new HashMap<>(16);
        HashMap<Long, BigDecimal> priceMap = new HashMap<>(16);
        HashMap<Long, String> coverPicMap = new HashMap<>(16);
        baseEntityPageData.getList().forEach(v -> {
            stringHashMap.put(v.getId(), v.getBbName());
            priceMap.put(v.getId(), v.getBbPrice());
            coverPicMap.put(v.getId(), v.getCoverPicture());
        });
        //查询商品最低价
        List<BlindBoxMallPageResVO> pageResVOSList = baseEntityPageData
                .getList()
                .stream()
                .map(c -> CompletableFuture.supplyAsync(() -> blindBoxMallService.getTheBottomPrice(c.getId()), pmsExecutor))
                .collect(Collectors.toList())
                .stream()
                .map(CompletableFuture::join)
                .filter(Objects::nonNull)
                .collect(Collectors.toList())
                .stream()
                .map(d -> {
                    BlindBoxMallPageResVO mallPageResVO = new BlindBoxMallPageResVO();
                    mallPageResVO.setBbName(stringHashMap.get(d.getBbId()));
                    mallPageResVO.setBottomPrice(d.getSellingPrice());
                    mallPageResVO.setCoverPicture(coverPicMap.get(d.getBbId()));
                    mallPageResVO.setId(d.getBbId());
                    stringHashMap.remove(d.getBbId());
                    return mallPageResVO;
                })
                .collect(Collectors.toList());
        //空商品 默认最低价为发售价
        ArrayList<BlindBoxMallPageResVO> resVOArrayList = new ArrayList<>(16);
        if (!CollUtil.isEmpty(stringHashMap)) {
            stringHashMap.forEach((k, v) -> {
                BlindBoxMallPageResVO mallPageResVO = new BlindBoxMallPageResVO();
                mallPageResVO.setBbName(v);
                mallPageResVO.setBottomPrice(priceMap.get(k));
                mallPageResVO.setCoverPicture(coverPicMap.get(k));
                mallPageResVO.setId(k);
                resVOArrayList.add(mallPageResVO);
            });
        }
        //链表合并
        pageResVOSList.addAll(resVOArrayList);
        PageData<BlindBoxMallPageResVO> resVOPageData = new PageData<>(pageResVOSList, baseEntityPageData.getTotal());

        return R.ok(resVOPageData);
    }

    /**
     * 在售盲盒分页
     *
     * @param blindBoxOnSaleQuery boq
     * @return r
     */
    @PostMapping("/onSaleBlindBoxPage")
    public R<BlindBoxOnSalePageResVO> onSaleBlindBoxPage(@Valid @RequestBody BlindBoxOnSaleQuery blindBoxOnSaleQuery) {
        BlindBoxOnSalePageResVO onSaleBlindBoxPage = blindBoxMallService.onSaleBlindBoxPage(blindBoxOnSaleQuery);
        return R.ok(onSaleBlindBoxPage);
    }

    /**
     * 在售盲盒详情
     *
     * @param id
     * @return
     */
    @GetMapping("/getOnSaleBlindBoxDetail/{id}")
    public R<BlindBoxOnSaleDetailResVO> getOnSaleBlindBoxDetail(@PathVariable Long id) {
        BlindBoxOnSaleDetailResVO blindBoxOnSaleDetailResVO = blindBoxMallService.getOnSaleBlindBoxDetail(id);
        return R.ok(blindBoxOnSaleDetailResVO);
    }

    /**
     * 盲盒上架商城
     *
     * @param userBlindBoxHoldList ubb
     * @return r
     */
    @Inner
    @PostMapping("/blindBoxesOnConsign")
    public R<String> blindBoxesOnConsign(@RequestBody List<UserBlindBoxHoldEntity> userBlindBoxHoldList) {
        if (blindBoxMallService.blindBoxesOnConsign(userBlindBoxHoldList)) {
            return R.ok();
        }
        return R.failed();
    }

    /**
     * 撤销盲盒寄售
     *
     * @param id 主键id
     * @return r
     */
    @Inner
    @GetMapping("/withdrawBlindBoxConsign/{id}")
    public R<String> withdrawBlindBoxConsign(@PathVariable Long id) {
        LambdaUpdateWrapper<BlindBoxMallEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .eq(BlindBoxMallEntity::getId, id)
                .set(BlindBoxMallEntity::getStatus, PmsCommonConstant.BLIND_BOX_WITHDRAW);
        if (blindBoxMallService.update(updateWrapper)) {
            return R.ok();
        }
        return R.failed();
    }

    @Inner
    @GetMapping("/lockBlindBoxStock/{id}/{userId}")
    public R<BlindBoxMallEntity> lockBlindBoxStock(@PathVariable Long id, @PathVariable Long userId) {
        BlindBoxMallEntity byId = blindBoxMallService.getById(id);
        if (Objects.equals(byId.getSellerId(), userId)) {
            //本人不能买本人盲盒
            return R.failed();
        }
        //库存锁定失败
        if (!byId.getStatus().equals(PmsCommonConstant.COLLECTION_CONSIGN)) {
            return R.failed();
        }
        //锁定库存
        LambdaUpdateWrapper<BlindBoxMallEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BlindBoxMallEntity::getId, id)
                .set(BlindBoxMallEntity::getStatus, PmsCommonConstant.COLLECTION_LOCKED);
        blindBoxMallService.update(updateWrapper);
        return R.ok(byId);
    }

    @Inner
    @GetMapping("/unlockBlindBoxStock/{id}")
    public R<String> unlockBlindBoxStock(@PathVariable Long id) {
        BlindBoxMallEntity byId = blindBoxMallService.getById(id);
        if (!byId.getStatus().equals(PmsCommonConstant.BLIND_BOX_LOCKED)) {
            return R.failed();
        }
        LambdaUpdateWrapper<BlindBoxMallEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BlindBoxMallEntity::getId, id)
                .set(BlindBoxMallEntity::getStatus, PmsCommonConstant.COLLECTION_CONSIGN);
        blindBoxMallService.update(updateWrapper);
        return R.ok();
    }
}